package cn.itcast.b_processDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

public class ProcessDefinitionTest {
	/**
	 * 通过下面的代码，默认读入该配置文件activiti.cfg.xml的信息
	 */
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	/**部署流程定义1.*/
	@Test
	public void deploymentProcessDefinition_Classpath() {
		//获取到部署的对象
		Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createDeployment()//创建一个部署对象
			.name("流程定义 ")//调价部署的名称
			.addClasspathResource("diagrams/helloworld/HelloWorld_cn.bpmn")//从ClassPath的资源中加载，一次只能加载一个文件，不能是文件夹
			.addClasspathResource("diagrams/helloworld/HelloWorld_cn.png")//从ClassPath的资源中加载，一次只能加载一个文件，不能是文件夹
			.deploy();//完成部署
		
		msyso("部署ID",deployment.getId());//部署ID:1
		msyso("部署名称",deployment.getName());//部署名称:Activiti入门程序
	}
	
	@Test
	public void deploymentProcessDefinition_zip() {
		
		InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld/HelloWorld_cn.zip");
		ZipInputStream zipInputStream = new ZipInputStream(in );
		//获取到部署的对象
		Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createDeployment()//创建一个部署对象
			.name("流程定义zip ")//调价部署的名称
			.addZipInputStream(zipInputStream)
			.deploy();//完成部署
		
		msyso("部署ID",deployment.getId());//部署ID:1
		msyso("部署名称",deployment.getName());//部署名称:Activiti入门程序
	}
	/**
	 * 查询流程定义3.
	 */
	@Test
	public void findProcessDefinition() {
		//获取到部署的对象
		List<ProcessDefinition> list = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createProcessDefinitionQuery()//创建一个流程定义的查询
			/**指定查询条件，where条件*/
//			.deploymentId(deploymentId)//使用部署对象ID查询
//			.processDefinitionId(processDefinitionId)//使用流程定义ID查询
//			.processDefinitionKey(processDefinitionKey)//使用流程定义的key查询
//			.processDefinitionKeyLike(processDefinitionKeyLike)//使用流程定义的模糊key查询
//			.processDefinitionNameLike(processDefinitionNameLike)//使用流程定义的模糊name查询
			/**排序*/
			.orderByProcessDefinitionVersion().asc()//按照版本的升序排列
			.orderByProcessDefinitionName().desc()//按照流程定义的名称降序排列
			
			/**返回的结果集*/
//			.singleResult()//返回一个集合列表
//			.count()//返回唯一结果集
//			.listPage(firstResult, maxResults)//分页查询
			.list();
			
		outPrintPD(list);
	}

	private void outPrintPD(List<ProcessDefinition> list) {
		if (list!=null&&list.size()>0) {
			for (ProcessDefinition pd : list) {
				msyso("流程ID",pd.getId());//流程定义的key+版本+随机生成数
				msyso("流程名称",pd.getName());//对应HelloWorld.bpmn文件中的name属性值
				msyso("流程的key",pd.getKey());//对应HelloWorld.bpmn文件中的ID属性值
				msyso("流程定义的版本",pd.getVersion());//当流程定义的key值相同的相同下，版本升级，默认1
				msyso("资源名称BPMN文件",pd.getResourceName());//
				msyso("资源名称png文件",pd.getDiagramResourceName());//
				msyso("部署对象ID",pd.getDeploymentId());//
				msyso("################################################","");//
			}
		}
	}
	
	/**
	 * 删除流程定义4.
	 */
	@Test
	public void deleteProcessDefinition() {
		String deploymentId = "1";
//		try {
//			/**
//			 * 不带级联的删除
//			 * 	只能删除没有启动的流程，如果流程启动，就会抛出异常*/
//			processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
//					.deleteDeployment(deploymentId);
//			msyso("删除成功","");//
//		} catch (Exception e) {
//			msyso("不删除成功","");//
//		}
		/**
		 * 级联的删除,不管是否启动流程
		 */
		processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.deleteDeployment(deploymentId,true);
		msyso("删除成功","");//
	}
	
	/**
	 * 查看图片5.
	 * @throws IOException 
	 */
	@Test
	public void viewPic() throws IOException {
		 String deploymentId = "301";
		 List<String> list = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
				 .getDeploymentResourceNames(deploymentId);
		 String resourceName = "";
		if (list != null && list.size() > 0) {
			for (String name : list) {
				if (name.indexOf(".png")>=0) {
					resourceName = name;
				}
			}
		}
		InputStream inputStream = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
				.getResourceAsStream(deploymentId, resourceName);
		File targetFile = new File("D:/"+resourceName);
		FileUtils.copyInputStreamToFile(inputStream, targetFile);
	}
	
	
	/**
	 * 查找最新的版本号的流程定义6.
	 * @throws IOException 
	 */
	@Test
	public void findLastVersionProcessDefinition() throws IOException {
		List<ProcessDefinition>  pds = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createProcessDefinitionQuery()
			.orderByProcessDefinitionVersion().asc()
			.list();
		Map map = new LinkedHashMap();
		if (pds != null && pds.size() > 0) {
			for (ProcessDefinition pd : pds) {
				map.put(pd.getKey(), pd);
			}
		}
		List list = new ArrayList(map.values());
		
		outPrintPD(list);
	}
	
	/**
	 * 根据指定的key删除流程定义
	 * @throws IOException 
	 */
	@Test
	public void deleteProcessDefinitionByKey() throws IOException {
		String processDefinitionKey = "helloworld_cn";
		List<ProcessDefinition>  pds = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createProcessDefinitionQuery()
			.processDefinitionKey(processDefinitionKey )
			.orderByProcessDefinitionVersion().asc()
			.list();
		
		
		if (pds != null && pds.size() > 0) {
			for (ProcessDefinition pd : pds) {
				processEngine.getRepositoryService().deleteDeployment(pd.getDeploymentId(), true);
			}
		}
	}
	
	private void msyso(String outPrintLabel, Object outPrintVal) {
		System.out.println(outPrintLabel+":"+outPrintVal);
	}
}
